import {
  _decorator,
  Component,
  instantiate,
  Node,
  ProgressBar,
  Tween,
  Vec3,
} from "cc";
import DataManager from "../../Global/DataManager";
import { EntityTypeEnum, IActor, InputTypeEnum, toFixed } from "../../Common";
import { EntityManager } from "../../Base/EntityManager";
import { ActorStateMachine } from "./ActorStateMachine";
import { ActorStateEnum, EventEnum } from "../../Enum";
import { WeaponManager } from "../Weapon/WeaponManager";
import { rad2Angle } from "../../Utils";
import EventManager from "../../Global/EventManager";
const { ccclass, property } = _decorator;

@ccclass("ActorManager")
export class ActorManager extends EntityManager {
  private weaponMgr: WeaponManager;
  bulletType: EntityTypeEnum;
  id: number;
  hp: ProgressBar;

  private targetPos: Vec3;
  private tw: Tween<Node>;

  start() {}

  init(data: IActor) {
    this.id = data.id;

    this.fsm = this.addComponent(ActorStateMachine);
    this.fsm.init(data.type);
    this.state = ActorStateEnum.Idle;

    this.targetPos = undefined;
    this.node.active = false;
    this.hp = this.node.getComponentInChildren(ProgressBar);

    let weaponPref = DataManager.Instance.mapPrefab.get(EntityTypeEnum.Weapon1);
    let weapon = instantiate(weaponPref);
    weapon.setParent(this.node);
    this.weaponMgr = weapon.addComponent(WeaponManager);
    this.weaponMgr.init(data);

    this.bulletType = data.bulletType;
  }

  tick(deltaTime: number) {
    if (this.id != DataManager.Instance.myPlayerId) {
      return;
    }

    if (DataManager.Instance.jm.playerInput.length() > 0) {
      const { x, y } = DataManager.Instance.jm.playerInput;

      EventManager.Instance.emit(EventEnum.ClientSync, {
        id: DataManager.Instance.myPlayerId,
        type: InputTypeEnum.ActorMove,

        direction: {
          x: toFixed(x),
          y: toFixed(y),
        },

        deltaTime,
      });

      // DataManager.Instance.applyInput({
      //   id: 1,
      //   type: InputTypeEnum.ActorMove,

      //   direction: {
      //     x,
      //     y,
      //   },

      //   deltaTime,
      // });

      // console.log(DataManager.Instance.state.actors[0].position);
    } else {
    }
  }

  render(data: IActor): void {
    this.renderPosition(data);
    this.renderDirection(data);
    this.renderHp(data);
  }

  renderPosition({ position }: IActor): void {
    const newPos = new Vec3(position.x, position.y);
    if (!this.targetPos) {
      this.node.setPosition(newPos);
      this.targetPos = new Vec3(newPos);
      this.node.active = true;
    } else if (!newPos.equals(this.targetPos)) {
      this.node.setPosition(this.targetPos);
      this.targetPos.set(newPos);

      this.tw?.stop();
      this.state = ActorStateEnum.Run;
      this.tw = new Tween(this.node)
        .to(0.1, { position: this.targetPos })
        .call(() => {
          this.state = ActorStateEnum.Idle;
        })
        .start();
    }
  }

  renderDirection(data: IActor) {
    if (data.direction.x < 0) {
      this.node.setScale(-1, 1);
      this.hp.reverse = true;
    } else {
      this.node.setScale(1, 1);
      this.hp.reverse = false;
    }

    let side = Math.sqrt(data.direction.x ** 2 + data.direction.y ** 2);
    let rad = Math.asin(data.direction.y / side);
    this.weaponMgr.node.setRotationFromEuler(0, 0, rad2Angle(rad));
  }

  renderHp(data: IActor) {
    this.hp.progress = data.hp / this.hp.totalLength;
  }
}
